using System;
using System.Xml.Serialization;
using SharpMud.Net;
using SharpMud.Net.Telnet.Session;

namespace SharpMud.Server.Systems.Net.Telnet
{
    [XmlRoot("Listener")]
    public class ListenerMetadatum<TTelnetSession> where TTelnetSession : TelnetSessionBase, IHasSessionState<TTelnetSession>, new()
    {
        private SharpMud.Server.Systems.Net.SLU                 _ListenOn;
        private SharpMud.DynamicTyping.AssembliedTypeLocation   _DefaultSessionState;

        public ListenerMetadatum()
        {
        }

        public ListenerMetadatum(string listenOn, SharpMud.DynamicTyping.AssembliedTypeLocation defaultSessionState)
            : this(SLU.Parse(listenOn), defaultSessionState)
        {
        }

        public ListenerMetadatum(SLU listenOn, SharpMud.DynamicTyping.AssembliedTypeLocation defaultSessionState)
        {
            this._ListenOn = listenOn;
            this._DefaultSessionState = defaultSessionState;
        }

        public System.Net.IPEndPoint GetEndpoint(int basePort)
        {
            return new System.Net.IPEndPoint(_ListenOn.Address, _ListenOn.GetAbsolutePort(basePort));
        }

        [XmlAttribute("ListenOn")]
        public string ListenOn
        {
            get
            {
                return _ListenOn.ToString();
            }
            set
            {
                _ListenOn = Net.SLU.Parse(value);
            }
        }

        [XmlIgnore]
        public Net.SLU SLU
        {
            get
            {
                return _ListenOn;
            }
            set
            {
                _ListenOn = value;
            }
        }

        [XmlElement("DefaultSessionState")]
        public SharpMud.DynamicTyping.AssembliedTypeLocation DefaultSessionStateType
        {
            get
            {
                return _DefaultSessionState;
            }
            set
            {
                _DefaultSessionState = value;
            }
        }

        public void Validate()
        {
            System.Type tDefaultSessionStateType = this._DefaultSessionState.AcquireType();
            ISessionState tempSessionState;
            try
            {
                tempSessionState = ((ISessionState)tDefaultSessionStateType.Assembly.CreateInstance(tDefaultSessionStateType.Name, false));
            }
            catch (InvalidCastException e)
            {
                throw new InvalidCastException("'DefaultSessionState' does not implement ISessionState", e);
            }

            if (!(tempSessionState is ISessionState<TTelnetSession>))
                throw new InvalidCastException("'DefaultSessionState' does not implement ISessionState<>");
        }

    }
}
